<?php

namespace App\Utility;

use App\Model\ImagesModel;
use Carbon\Carbon;
use EasySwoole\Utility\File;
use EasySwoole\EasySwoole\Config;
use Qiniu\Storage\BucketManager;
use Qiniu\Storage\UploadManager;
use Qiniu\Auth;

class Filesystem{

    protected $files;
    protected $adminId;

    public function __construct($files = null){
        $this->files = $files;
        $this->adminId = 0;
    }

    /**
     * 保存文件到指定文件夹
     * 指定文件夹下面都是基于时间来生成目录
     * @param string $dirname
     * @return bool|string
     */
    public function storeAs($dirname='upload'){
        $name = $this->hash();
        $time = date('Y-m-d');
        $ext  = $this->getExtension();
        $tmpfile = $this->getRealPath();
        $fileName = $dirname.'/'.$time.'/'.$name.'.'.$ext;
        $filePath = trim($this->getStaticRoot(), '/').'/'.$fileName;
        $res = File::createFile($filePath,file_get_contents($tmpfile));
        $domain = $this->getDoMain();
        unlink($tmpfile);
        if($res === false) return false;
        return trim($domain, '/').'/'.$fileName;
    }

    /**
     * 七牛云上传
     * @param string $dirname
     * @return bool|string
     * @throws \Exception
     */
    public function qiNiuAs(){
        $name = $this->hash();
        $time = date('Y-m-d');
        $ext  = $this->getExtension();
        $fileName = $time.'/'.$name.'.'.$ext;
        $upManager = new UploadManager();
        $tmpfile = $this->getRealPath();
        $qiniu = $this->getQiNiuConfig();
        $auth = new Auth($qiniu['access'], $qiniu['secret']);
        $token = $auth->uploadToken($qiniu['bucket']);
        //$error保留了请求响应的信息，失败情况下ret 为none
        list($ret, $error) = $upManager->putFile($token, $fileName, $tmpfile);
        unlink($tmpfile);
        if($error) return false;
        //资源管理
        $this->storeImage($fileName,$name,$qiniu['domain']);
        return $qiniu['domain'].$ret['key'];
    }

    /**
     * 批量删除七牛云资源
     * @param array $keys
     * @return bool
     */
    public function qiNiuBatch($keys = []){
        $qiniu = $this->getQiNiuConfig();
        $auth = new Auth($qiniu['access'], $qiniu['secret']);
        $config = new \Qiniu\Config();
        $bucketManager = new BucketManager($auth, $config);
        //每次最多不能超过1000个
        $ops = $bucketManager->buildBatchDelete($qiniu['bucket'], $keys);
        list($ret, $err) = $bucketManager->batch($ops);
        if ($err) {
            return false;
        }
        return $ret;
    }


    /**
     * 设置上传管理员ID
     * @param int $id
     * @return $this
     */
    public function setAdminId($id = 0){
        $this->adminId = $id;
        return $this;
    }

    protected function storeImage($path='',$hash='',$domain=''){
        $model = new ImagesModel();
        $info = $model->where('hash',$hash)->first();
        if($info){
            return true;
        }
        $store = [
            'path' => $path,
            'hash' => $hash,
            'domain' => $domain,
            'type' => $this->getType(),
            'admin_id' => $this->adminId,
            'size' => $this->getSize(),
            'created_at' => Carbon::now()
        ];
        return $model->create($store);
    }

    /**
     * 获取七牛云配置
     * @return array|mixed|null
     */
    protected function getQiNiuConfig(){
        return Config::getInstance()->getConf('qiniu');
    }

    /**
     * 删除指定文件
     * @param $filename
     * @return bool
     */
    public function destroy($filename){
        if($this->exists($filename)){
            $filePath = $this->getStaticRoot().$filename;
            return unlink($filePath);
        }
        return false;
    }

    /**
     * 获得指定文件目录或目录文件数组
     * @param string $dirname
     * @return array|bool
     */
    public function scan($dirname='image'){
        $filePath = $this->getStaticRoot().$dirname;
        return File::scanDirectory($filePath);
    }

    /**
     * 判断文件是否存在
     * @param $path
     * @return bool
     */
    public function exists($filename){
        $filePath = $this->getStaticRoot().$filename;
        return file_exists($filePath);
    }

    /**
     * 返回项目静态文件夹的绝对地址
     * @return string
     */
    public function getStaticRoot(){
        return Config::getInstance()->getConf('STATIC_ROOT');
    }

    /**
     * 返回项目路由
     * @return string
     */
    public function getDoMain(){
        return Config::getInstance()->getConf('APP_URL');
    }

    /**
     * 获取扩展名
     * @return mixed
     */
    public function getExtension(){
        return pathinfo($this->files->getClientFilename(), PATHINFO_EXTENSION);
    }

    /**
     * 临时文件名称
     * @return mixed
     */
    public function getRealPath(){
        return $this->files->getTempName();
    }

    /**
     * 获取文件大小
     * @return string
     */
    public function getSize(){
        $size = $this->files->getSize();
        return $this->bytesToSize($size);
    }

    /**
     * 字节转化成单位
     * @param $size
     * @return string
     */
    public function bytesToSize($size){
        $units = array(' B', ' KB', ' MB', ' GB', ' TB');
        for ($i = 0; $size >= 1024 && $i < 4; $i++){
            $size /= 1024;
        }
        return round($size, 2).$units[$i];
    }

    /**
     * 获取文件类型
     * @return mixed
     */
    public function getType(){
        return $this->files->getClientMediaType();
    }

    /**
     * 生成hash值
     * @return string
     */
    public function hash(){
        return hash_file('md5',$this->getRealPath());
    }
}
